/**
  ******************************************************************************
  * @file    xxx.c 
  * @author  SD Electronics xxx
  * @version V1.0
  * @date    xx-xx-xx
  * @brief   xxxxxxxxxxxxxxxxxx.
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "sd_profile_fbl.h"
#include <stdio.h>
#include <string.h>

#include "gap_api.h"
#include "gatt_api.h"
#include "gatt_sig_uuid.h"
#include "co_log.h"
#include "sd_common.h"
#include "sd_dev_bt.h"

/*********************************FBL Profile***********************************/

#define SDFBL_CHAR1_VALUE_LEN  512
uint8_t SDFBL_char1_value[SDFBL_CHAR1_VALUE_LEN] = {0};

#define SDFBL_CHAR1_DESC_LEN   5
const uint8_t SDFBL_char1_desc[SDFBL_CHAR1_DESC_LEN] = "write";


#define SDFBL_CHAR2_VALUE_LEN  512
uint8_t SDFBL_char2_value[SDFBL_CHAR2_VALUE_LEN] = {0};

#define SDFBL_CHAR2_CCC_LEN   2
uint8_t SDFBL_char2_ccc[SDFBL_CHAR2_CCC_LEN] = {0};

#define SDFBL_CHAR2_DESC_LEN   6
const uint8_t SDFBL_char2_desc[SDFBL_CHAR2_DESC_LEN] = "notify";


/*
 * GLOBAL VARIAFBLS (????)
 */
uint8_t SDFBL_svc_id = 0;
uint8_t fbl_local_conn_idx;   //!< Connection index

/**
  * @brief  SDFBL_profile_att_taFBL
  * @param  None
  * @note	xxx
  * @retval None
  */
gatt_attribute_t SDFBL_profile_att_taFBL[SDFBL_IDX_NB] =
{
    // SDFBL gatt Service Declaration
[SDFBL_IDX_SERVICE]                    ={
                                            { UUID_SIZE_2, UUID16_ARR(GATT_PRIMARY_SERVICE_UUID) },     /* UUID */
                                            GATT_PROP_READ,                                             /* Permissions */
                                            UUID_SIZE_2,                                                /* Max size of the value */     /* Service UUID size in service declaration */
                                            NULL,                                      /* Value of the attribute */    /* Service UUID value in service declaration */
                                        },

// Characteristic 1 Declaration           
[SDFBL_IDX_CHAR1_DECLARATION]          =   {
                                            { UUID_SIZE_2, UUID16_ARR(GATT_CHARACTER_UUID) },           /* UUID */
                                            GATT_PROP_READ,                                             /* Permissions */
                                            0,                                                          /* Max size of the value */
                                            NULL,                                                       /* Value of the attribute */
                                        },
// Characteristic 1 Value                  
[SDFBL_IDX_CHAR1_VALUE]                =   {
                                            { UUID_SIZE_2, ("\xff\xff\xff\xff") },                 /* UUID */
                                            GATT_PROP_WRITE | GATT_PROP_WRITE_CMD | GATT_PROP_WRITE_REQ,                                        /* Permissions */
                                            SDFBL_CHAR1_VALUE_LEN,                                         /* Max size of the value */
                                            NULL,                                                       /* Value of the attribute */    /* Can assign a buffer here, or can be assigned in the application by user */
                                        },

// Characteristic 1 User Description
[SDFBL_IDX_CHAR1_DES]     =             {
                                            { UUID_SIZE_2, UUID16_ARR(GATT_CHAR_USER_DESC_UUID) },      /* UUID */
                                            GATT_PROP_READ | GATT_PROP_WRITE,                                             /* Permissions */
                                            SDFBL_CHAR1_DESC_LEN,                                          /* Max size of the value */
                                            (uint8_t *)SDFBL_char1_desc,                                   /* Value of the attribute */
                                        },                                            

// Characteristic 2 Declaration
[SDFBL_IDX_CHAR2_DECLARATION]          =  {
                                            { UUID_SIZE_2, UUID16_ARR(GATT_CHARACTER_UUID) },           /* UUID */
                                            GATT_PROP_READ,                                             /* Permissions */
                                            0,                                                          /* Max size of the value */
                                            NULL,                                                       /* Value of the attribute */
                                        },
// Characteristic 2 Value   
[SDFBL_IDX_CHAR2_VALUE]                =   {
                                            { UUID_SIZE_2, ("\xff\xff\xff\xff") },                 /* UUID */
                                            GATT_PROP_NOTI,                                             /* Permissions */
                                            SDFBL_CHAR2_VALUE_LEN,                                         /* Max size of the value */
                                            NULL,                                                       /* Value of the attribute */	/* Can assign a buffer here, or can be assigned in the application by user */
                                        },

// Characteristic 2 client characteristic configuration
[SDFBL_IDX_CHAR2_CFG]                  =  {
                                            { UUID_SIZE_2, UUID16_ARR(GATT_CLIENT_CHAR_CFG_UUID) },     /* UUID */
                                            GATT_PROP_WRITE | GATT_PROP_READ,                           /* Permissions */
                                            SDFBL_CHAR2_CCC_LEN,                                           /* Max size of the value */
                                            NULL,                                                       /* Value of the attribute */    /* Can assign a buffer here, or can be assigned in the application by user */
                                        },
                                                                                    // Characteristic 1 User Description
[SDFBL_IDX_CHAR2_DES]     =             {
                                            { UUID_SIZE_2, UUID16_ARR(GATT_CHAR_USER_DESC_UUID) },      /* UUID */
                                            GATT_PROP_READ | GATT_PROP_WRITE,                                             /* Permissions */
                                            SDFBL_CHAR2_DESC_LEN,                                          /* Max size of the value */
                                            (uint8_t *)SDFBL_char2_desc,                                   /* Value of the attribute */
                                        },     
};

/**
  * @brief  SDFBL_gatt_read_cb
  * @param  None
  * @note	xxx
  * @retval None
  */
static void SDFBL_gatt_read_cb(uint8_t *p_read, uint16_t *len, uint16_t att_idx)
{
    switch (att_idx)
    {
        case SDFBL_IDX_CHAR1_DES:
            *len = SDFBL_CHAR1_DESC_LEN;
            memcpy(p_read, SDFBL_char1_desc, SDFBL_CHAR1_DESC_LEN);
        break;
        case SDFBL_IDX_CHAR2_DES:
            *len = SDFBL_CHAR2_DESC_LEN;
            memcpy(p_read, SDFBL_char2_desc, SDFBL_CHAR2_DESC_LEN);
        break;
        default:
        break;
    }
}

/**
  * @brief  SDFBL_gatt_write_cb
  * @param  None
  * @note	xxx
  * @retval None
  */
static void SDFBL_gatt_write_cb(uint8_t *write_buf, uint16_t len, uint16_t att_idx)
{
    if (att_idx == SDFBL_IDX_CHAR1_VALUE)
    {
        /* ?????---??????? */
        //if(EN_UART_TRANSMODE_TRANSFER == SDGetUart_TPMODE())
        {
            /* ???? */
            memcpy(SDFBL_char1_value, write_buf, len);
            //??????
            RecvDataParse(write_buf, len);

            #if 1
            //????
            for(int i = 0; i < len; i++)
            {
                printf("Write request: len: %d, 0x%x \r\n", len, write_buf[i]);
            }
            #endif
        }

        /* ???????? */

    }
    
	uint16_t uuid = BUILD_UINT16( SDFBL_profile_att_taFBL[att_idx].uuid.p_uuid[0], SDFBL_profile_att_taFBL[att_idx].uuid.p_uuid[1] );
	if (uuid == GATT_CLIENT_CHAR_CFG_UUID)
    {
		LOG_INFO("Notification status changed\r\n");

    }
}

/**
  * @brief  SDFBL_gatt_msg_handler
  * @param  None
  * @note	xxx
  * @retval None
  */
static uint16_t SDFBL_gatt_msg_handler(gatt_msg_t *p_msg)
{
    switch(p_msg->msg_evt)
    {
        case GATTC_MSG_READ_REQ:
            SDFBL_gatt_read_cb((uint8_t *)(p_msg->param.msg.p_msg_data), &(p_msg->param.msg.msg_len), p_msg->att_idx);
            break;
        
        case GATTC_MSG_WRITE_REQ:
            SDFBL_gatt_write_cb((uint8_t*)(p_msg->param.msg.p_msg_data), (p_msg->param.msg.msg_len), p_msg->att_idx);
            break;
        case GATTC_MSG_LINK_CREATE:
            fbl_local_conn_idx = p_msg->conn_idx;
            break;
        case GATTC_MSG_LINK_LOST:
            
            break;
        default:
            break;
    }
    return p_msg->param.msg.msg_len;
}

/**
  * @brief  SDFBL_ntf_data
  * @param  None
  * @note	xxx
  * @retval None
  */
void SDFBL_ntf_data(uint8_t *data, uint16_t len)
{
    gatt_ntf_t ntf_att;
    ntf_att.att_idx = SDFBL_IDX_CHAR2_VALUE;
    ntf_att.conidx = fbl_local_conn_idx;
    ntf_att.svc_id = SDFBL_svc_id;
    ntf_att.data_len = len;
    ntf_att.p_data = data;
    gatt_notification(ntf_att);
}

/**
  * @brief  SDFBL_gatt_add_service
  * @param  None
  * @note	xxx
  * @retval None
  */
void SDFBL_gatt_add_service(PST_BT_PARAM pstBTParam, PST_BLE_CNT_PHY pstFBLPhy)
{
    if(pstBTParam != NULL)
    {
        gatt_service_t SDFBL_profile_svc;
        SDFBL_profile_att_taFBL[SDFBL_IDX_SERVICE].p_data = (uint8_t* )pstBTParam->service_uuid;
        memcpy(SDFBL_profile_att_taFBL[SDFBL_IDX_CHAR1_VALUE].uuid.p_uuid,(uint8_t* )pstBTParam->notify_uuid, UUID_SIZE_2);
        memcpy(SDFBL_profile_att_taFBL[SDFBL_IDX_CHAR2_VALUE].uuid.p_uuid,(uint8_t* )pstBTParam->write_uuid, UUID_SIZE_2);
        SDFBL_profile_svc.p_att_tb = SDFBL_profile_att_taFBL;
        SDFBL_profile_svc.att_nb = SDFBL_IDX_NB;
        SDFBL_profile_svc.gatt_msg_handler = SDFBL_gatt_msg_handler;
        SDFBL_svc_id = gatt_add_service(&SDFBL_profile_svc);
    }
    else
    {
        gatt_service_t SDFBL_profile_svc;
        SDFBL_profile_att_taFBL[SDFBL_IDX_SERVICE].p_data = (uint8_t* )pstFBLPhy->service_uuid;
        memcpy(SDFBL_profile_att_taFBL[SDFBL_IDX_CHAR1_VALUE].uuid.p_uuid,(uint8_t* )pstFBLPhy->notify_uuid, UUID_SIZE_2);
        memcpy(SDFBL_profile_att_taFBL[SDFBL_IDX_CHAR2_VALUE].uuid.p_uuid,(uint8_t* )pstFBLPhy->write_uuid, UUID_SIZE_2);
        SDFBL_profile_svc.p_att_tb = SDFBL_profile_att_taFBL;
        SDFBL_profile_svc.att_nb = SDFBL_IDX_NB;
        SDFBL_profile_svc.gatt_msg_handler = SDFBL_gatt_msg_handler;
        SDFBL_svc_id = gatt_add_service(&SDFBL_profile_svc);
    }
}

/******************* (C) COPYRIGHT 2011 ShenZhenShiding electronics **************************/
